package com.example.news.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.news.mapper.UserMapper;
import com.example.news.pojo.entity.User;
import com.example.news.pojo.form.*;
import com.example.news.pojo.vo.LoginVo;
import com.example.news.service.AuthService;
import com.example.news.utils.JwtHelper;
import com.example.news.utils.MD5Util;
import com.example.news.utils.MailUtils;
import com.example.news.utils.result.Result;
import com.example.news.utils.result.ResultCodeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl extends ServiceImpl<UserMapper, User>
        implements AuthService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtHelper jwtHelper;
    @Autowired
    private MailUtils mailUtils;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private static final String EMAIL_AUTH_PRIM = "captcha:email:";
    private static final String EMAIL_LOGIN_PRIM = "captcha:email:login:";
    private static final String EMAIL_CHANGE_PW_PRIM = "captcha:email:pw:";
    private static final String EMAIL_CHANGE_EM_OLD_PRIM = "captcha:email:em:old:";
    private static final String EMAIL_CHANGE_EM_NEW_PRIM = "captcha:email:em:new:";

    @Override
    public Result<String> userRegister(RegisterForm registerForm) {
        String captcha =(String)redisTemplate.opsForValue().get(EMAIL_AUTH_PRIM+registerForm.getEmail());
        //账号密码判断
        if (captcha != null && !StringUtils.isEmpty(registerForm.getCaptcha()) && captcha.equalsIgnoreCase(registerForm.getCaptcha())) {
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, registerForm.getUsername());
            User user = userMapper.selectOne(queryWrapper);
            if (user != null) {
                return Result.build(null, ResultCodeEnum.USERNAME_USED);
            }
            User user1=new User();
            BeanUtils.copyProperties(registerForm,user1);
            //对密码进行加密
            user1.setPassword(MD5Util.encrypt(registerForm.getPassword()));
            this.save(user1);
            return Result.ok(null,"注册成功！");
        }else{
            return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
        }
    }

    @Override
    public Result<LoginVo> userLogin(LoginForm loginForm) {
        //账号查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, loginForm.getUsername());
        User loginUser = userMapper.selectOne(queryWrapper);
        //账号判断
        if (loginUser == null) {
            return Result.build(null, ResultCodeEnum.USERNAME_ERROR);
        }
        //账号密码判断
        if (!StringUtils.isEmpty(loginForm.getPassword()) && loginUser.getPassword().equals(MD5Util.encrypt(loginForm.getPassword()))) {
            //账号密码正确
            //根据用户唯一标识生成token
            LoginVo loginVo = new LoginVo();
            loginVo.setToken(jwtHelper.createToken(Long.valueOf(loginUser.getId())));
            return Result.ok(loginVo);
        }
        //密码错误
        return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
    }

    @Override
    public Result<LoginVo> userLoginByEmail(EmailLoginForm emailLoginForm) {
        //账号查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, emailLoginForm.getEmail());
        User loginUser = userMapper.selectOne(queryWrapper);
        //账号判断
        if (loginUser == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }
        String captcha =(String)redisTemplate.opsForValue().get(EMAIL_LOGIN_PRIM+emailLoginForm.getEmail());
        //账号密码判断
        if (captcha != null && !StringUtils.isEmpty(emailLoginForm.getCaptcha()) && captcha.equalsIgnoreCase(emailLoginForm.getCaptcha())) {
            //验证码正确
            //根据用户唯一标识生成token
            LoginVo loginVo = new LoginVo();
            loginVo.setToken(jwtHelper.createToken(Long.valueOf(loginUser.getId())));
            return Result.ok(loginVo);
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<String> getLoginCaptcha(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email)
                .eq(User::getDeleted, 0);
        if(!userMapper.exists(queryWrapper)){
            return Result.build(null,ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }
        new Thread(() -> {
            String captcha = mailUtils.getCode();
            redisTemplate.opsForValue().set(EMAIL_LOGIN_PRIM+email,captcha,5L, TimeUnit.MINUTES);
            mailUtils.sendMail(email,"您的登录验证码为："+captcha+" 五分钟之内有效","新闻发布管理平台验证码");
        }).start();
        return Result.ok("null","邮件成功发送！");
    }

    @Override
    public Result<String> getRegisterCaptcha(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email)
                .eq(User::getDeleted, 0);
        if(userMapper.exists(queryWrapper)){
            return Result.build(null,ResultCodeEnum.EMAIL_USED);
        }
        new Thread(() -> {
            String captcha = mailUtils.getCode();
            redisTemplate.opsForValue().set(EMAIL_AUTH_PRIM+email,captcha,5L, TimeUnit.MINUTES);
            mailUtils.sendMail(email,"您的注册验证码为："+captcha+" 五分钟之内有效","新闻发布管理平台验证码");
        }).start();
        return Result.ok("null","邮件成功发送！");
    }
    @Override
    public Result<String> changeUserPassword(ChangePwdForm changePwdForm){
        //账号查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, changePwdForm.getUsername());
        User user = userMapper.selectOne(queryWrapper);
        //账号判断
        if (user == null) {
            return Result.build(null, ResultCodeEnum.USERNAME_ERROR);
        }
        //账号密码判断
        if (!StringUtils.isEmpty(user.getPassword()) && user.getPassword().equals(MD5Util.encrypt(user.getPassword()))) {
            //账号密码正确
            // 使用 LambdaUpdateWrapper 修改指定属性
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getId, user.getId())
                    .set(User::getPassword, MD5Util.encrypt(changePwdForm.getNewPassword()));
            this.update(lambdaUpdateWrapper); // 执行更新操作
            return Result.ok(null,"修改成功！");
        }
        //密码错误
        return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
    }
    @Override
    public Result<String> getChangePwdCaptcha(String email){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email)
                .eq(User::getDeleted, 0);
        if(!userMapper.exists(queryWrapper)){
            return Result.build(null,ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }
        new Thread(() -> {
            String captcha = mailUtils.getCode();
            redisTemplate.opsForValue().set(EMAIL_CHANGE_PW_PRIM+email,captcha,5L, TimeUnit.MINUTES);
            mailUtils.sendMail(email,"您的验证码为："+captcha+" 五分钟之内有效","新闻发布管理平台验证码");
        }).start();
        return Result.ok("null","邮件成功发送！");
    }

    @Override
    public Result<String> changeUserPwdByEmail(ChangePwdByEmailForm changePwdByEmailForm){
        //账号查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, changePwdByEmailForm.getEmail());
        User user = userMapper.selectOne(queryWrapper);
        //账号判断
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }

        String captcha =(String)redisTemplate.opsForValue().get(EMAIL_CHANGE_PW_PRIM+changePwdByEmailForm.getEmail());
        //账号密码判断
        if (captcha != null && !StringUtils.isEmpty(changePwdByEmailForm.getCaptcha()) && captcha.equalsIgnoreCase(changePwdByEmailForm.getCaptcha())) {
            //验证码正确
            // 使用 LambdaUpdateWrapper 修改指定属性
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getId, user.getId())
                    .set(User::getPassword, MD5Util.encrypt(changePwdByEmailForm.getNewPassword()));
            this.update(lambdaUpdateWrapper); // 执行更新操作
            return Result.ok(null,"修改成功！");
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

}
